package cn.lanqiao.bigDate.service.sys.impl;

import cn.lanqiao.bigDate.entity.sys.SysRole;
import cn.lanqiao.bigDate.entity.sys.SysUser;
import cn.lanqiao.bigDate.entity.sys.SysUserRole;
import cn.lanqiao.bigDate.mapper.sys.SysRoleMapper;
import cn.lanqiao.bigDate.mapper.sys.SysUserMapper;
import cn.lanqiao.bigDate.mapper.sys.SysUserRoleMapper;
import cn.lanqiao.bigDate.service.sys.SysUserRoleService;
import cn.lanqiao.bigDate.service.sys.SysUserService;
import cn.lanqiao.common.utils.MD5Util;
import cn.lanqiao.common.utils.RandomUtil;
import com.alibaba.druid.util.StringUtils;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.*;
import java.util.regex.Pattern;

@Service
public class SysUserServiceImpl implements SysUserService{

    @Resource
    private SysUserRoleService sysUserRoleService;

    @Resource
    private SysUserMapper sysUserMapper;

    @Resource
    private SysRoleMapper sysRoleMapper;

    @Resource
    private SysUserRoleMapper sysUserRoleMapper;

    @Override
    public IPage<SysUser> findByPage(Page<SysUser> page, String str) {
        JSONObject o = JSONObject.parseObject(str);
        QueryWrapper<SysUser> wrapper = new QueryWrapper<>();
        wrapper.orderByAsc("id");
        if(!o.get("status").equals("-1")){
            wrapper.eq("user_type", o.get("status"));
        }
        if(!o.get("keywords").equals("")){
            String s = o.get("keywords").toString();
            if(!o.get("status").equals("-1")){
                wrapper.and(e ->
                        e
                        .like("login_name", s).or()
                        .like("user_name", s).or()
                        .like("remark", s)
                        );
            }else {
                wrapper.like("login_name", s).or();
                wrapper.like("user_name", s).or();
                wrapper.like("remark", s);
            }
        }
        Page<SysUser> sysUserPage = sysUserMapper.selectPage(page, wrapper);
        List<SysUser> records = sysUserPage.getRecords();
        records.forEach(e -> e.setPassword(""));
        sysUserPage.setRecords(records);
        return sysUserPage;
    }

    @Override
    public SysUser findSysUserOne(Long id) {
        QueryWrapper<SysUser> wrapper = new QueryWrapper<>();
        wrapper.eq("id",id);
        SysUser sysUser = sysUserMapper.selectOne(wrapper);
        sysUser.setPassword("");
        return sysUser;
    }

    @Override
    public SysUser findSysUserOne(String loginName) {
        return sysUserMapper.selectOne(new QueryWrapper<SysUser>().eq("login_name",loginName));
    }

    @Override
    public SysUser findSysUserOne(Long id, Boolean clearPassword) {
        QueryWrapper<SysUser> wrapper = new QueryWrapper<>();
        wrapper.eq("id",id);
        return sysUserMapper.selectOne(wrapper);
    }


    @Override
    public Boolean saveSysUser(SysUser sysUser) {
        // 用户规则校验
        if(!checkSysUser(sysUser)){
            return false;
        }
        sysUser.setCreateTime(LocalDateTime.now());     // 创建时间
        sysUser.setLoginDate(LocalDateTime.now());      // 登录时间
        sysUser.setUpdateTime(LocalDateTime.now());     // 更新时间
        String salt = RandomUtil.getRandom(4);    // 盐随机数
        sysUser.setSalt(salt);
        String password = sysUser.getPassword();
        sysUser.setPassword(MD5Util.md5(password + salt));
        int i = sysUserMapper.insert(sysUser);
        return i > 0;
    }

    @Override
    public Boolean updateSysUser(SysUser sysUser) {
        if (sysUser != null && sysUser.getId() != null) {
            // 用户规则校验
            if(!checkSysUser(sysUser)){
                return false;
            }
            Long id = sysUser.getId();
            SysUser user = findSysUserOne(id);
            user.setUpdateTime(LocalDateTime.now());
            String password = sysUser.getPassword();
            if (password != null && !password.equals("")) {
                String salt = user.getSalt();
                user.setPassword(MD5Util.md5(password + salt));
            }else {
                SysUser u = findSysUserOne(user.getId(),false);
                user.setPassword(u.getPassword());
            }
            user.setUserName(sysUser.getUserName());
            user.setUserType(sysUser.getUserType());
            user.setEmail(sysUser.getEmail());
            user.setPhonenumber(sysUser.getPhonenumber());
            user.setSex(sysUser.getSex());
            user.setAvatar(sysUser.getAvatar());
            user.setStatus(sysUser.getStatus());
            user.setDelFlag(sysUser.getDelFlag());
            user.setLoginIp(sysUser.getLoginIp());
            user.setRemark(sysUser.getRemark());
            user.setUpdateBy(sysUser.getUpdateBy());
            int i = sysUserMapper.updateById(user);
            // 更新角色


            return i == 1;
        }
        return false;
    }

    @Override
    public Boolean deleteSysUser(String ids) {
        if(!StringUtils.isEmpty(ids)){
            String[] id = ids.split(",");
            List<String> idList = Arrays.asList(id);
            int i = sysUserMapper.deleteBatchIds(idList);   // 删除用户
            deleteSysRoleByUserId(ids);     // 删除映射
            return i > 0;
        }
        return false;
    }

    @Override
    public List<SysRole> getRolesById(String id) {
        QueryWrapper<SysUserRole> sysUserRoleWrapper = new QueryWrapper<>();
        sysUserRoleWrapper.eq("user_id", id);
        List<SysUserRole> sysUserRoles = sysUserRoleMapper.selectList(sysUserRoleWrapper);
        List<Long> ids = new ArrayList<>();
        sysUserRoles.forEach(e -> ids.add(e.getRoleId()));
        if(ids.isEmpty()){
            return null;
        }
        QueryWrapper<SysRole> wrapper = new QueryWrapper<>();
        wrapper.in("id", ids);
        return sysRoleMapper.selectList(wrapper);
    }

    @Override
    public Boolean saveRoleBySysUser(SysUser sysUser) {
        if(sysUser.getRole() == null || sysUser.getRole().isEmpty()){
            return true;
        }
        QueryWrapper<SysRole> wrapper = new QueryWrapper<>();
        wrapper.in("role_name", sysUser.getRole());
        List<SysRole> sysRoles = sysRoleMapper.selectList(wrapper);
        boolean[] res = {true};
        sysRoles.forEach(e -> {
            SysUserRole sysUserRole = new SysUserRole();
            sysUserRole.setUserId(sysUser.getId());
            sysUserRole.setRoleId(e.getId());
            int i = sysUserRoleMapper.insert(sysUserRole);
            res[0] = res[0] && (i == 1);
        });
        return res[0];
    }

    @Override
    public Boolean saveOrUpdateRoleBatchBySysUser(SysUser sysUser) {
        // 清除所有与该用户有关的角色映射
        Boolean isDel = deleteSysRoleByUserId(sysUser.getId());
        if(sysUser.getRole() == null || sysUser.getRole().isEmpty()){
            return isDel;
        }
        QueryWrapper<SysRole> srWrapper = new QueryWrapper<>();
        srWrapper.in("role_name", sysUser.getRole());
        List<SysRole> nowSysRoles = sysRoleMapper.selectList(srWrapper);
        List<SysUserRole> sysUserRoleList = new ArrayList<>();
        nowSysRoles.forEach(e -> {
            SysUserRole sysUserRole = new SysUserRole();
            sysUserRole.setUserId(sysUser.getId());
            sysUserRole.setRoleId(e.getId());
            sysUserRoleList.add(sysUserRole);
        });
        return sysUserRoleService.saveOrUpdateBatch(sysUserRoleList);
    }

    @Override
    public Boolean deleteSysRoleByUserId(Long id){
        List<SysRole> rolesById = getRolesById(id + "");
        if (rolesById == null || rolesById.isEmpty()){
            return true;
        }
        QueryWrapper<SysUserRole> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id", id);
        int i = sysUserRoleMapper.delete(wrapper);
        return i > 0;
    }

    @Override
    public Boolean deleteSysRoleByUserId(String idStr){
        String[] ids = idStr.split(",");
        List<String> idList = Arrays.asList(ids);
        QueryWrapper<SysUserRole> wrapper = new QueryWrapper<>();
        wrapper.in("user_id", idList);
        int i = sysUserRoleMapper.delete(wrapper);
        return i > 0;
    }

    @Override
    public Boolean deleteSysRoleByUserId(List<Long> ids){
        QueryWrapper<SysUserRole> wrapper = new QueryWrapper<>();
        wrapper.in("user_id", ids);
        int i = sysUserRoleMapper.delete(wrapper);
        return i > 0;
    }

    @Override
    public Boolean checkSysUser(SysUser sysUser){
        System.out.println("\n");
        System.out.println(">>>>>>>>> sysUser >>>>>>>>");
        System.out.println(sysUser);
        System.out.println(">>>>>>>>> sysUser >>>>>>>>");
        Set<Boolean> checked = new HashSet<>();
        checked.add(true);
        checked.add(Pattern.matches("^[a-zA-Z][a-zA-Z0-9_]{4,15}$", sysUser.getLoginName()));
        checked.add(Pattern.matches("^([a-zA-Z0-9_-]|[\\u4E00-\\u9FA5]){4,20}$", sysUser.getUserName()));
        if(sysUser.getId() != null && !sysUser.getPassword().equals("")){
            checked.add(Pattern.matches("^(?=.*\\d)(?=.*[a-zA-Z])[\\da-zA-Z~!@#$%^&*.]{6,18}$", sysUser.getPassword()));
        }
        checked.add(Pattern.matches("^\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*$", sysUser.getEmail()));
        checked.add(Pattern.matches("^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\\d{8}$", sysUser.getPhonenumber()));
        checked.add(Pattern.matches("^.{0,64}$", sysUser.getRemark()));
        return checked.size() == 1;
    }

    public static void main(String[] args) {
        SysUserServiceImpl sysUserService = new SysUserServiceImpl();
        SysUser user = new SysUser(
                1L, 1L,
                "user_1", "魔理沙DAZE", "00", "3038488053@ry.com", "13708138962",
                "2", "", "123456AAaa.", "1234", "0",
                "0", "127.0.0.1", LocalDateTime.now(), "Marisa", LocalDateTime.now(),
                "Marisa",LocalDateTime.now(),"你好，这是测试文本。",null
        );
        Boolean res = sysUserService.checkSysUser(user);
        System.out.println(res);
    }
}
